<?php
namespace decorator\version2;

//装饰器接口
interface ClothesDecorator
{
    public function beforeDecorate();
    public function afterDecorate();
}

//待装饰的主体类
class Person 
{
    private $_name;
    protected $_decorator = [];

    public function __construct($name)
    {
        $this->_name = $name;
    }

    public function addDecorate(ClothesDecorator $decorator) //在主体类中注入装饰器
    {
        $this->_decorator[] = $decorator;
    }

    public function show() 
    {
        $this->beforeDecorate(); //出门前着装打扮等
        echo "{$this->_name}出门了\n";
        $this->afterDecorate(); //出门后脱衣服卸妆等
    }

    public function beforeDecorate() 
    {
        foreach($this->_decorator as $decorator) 
        {
            $decorator->beforeDecorate();
        }
    }

    public function afterDecorate() 
    {
        $decorators = array_reverse($this->_decorator); //将数组反转，先进后出，个人感觉没必要，除非需要做反向对称操作
        foreach($decorators as $decorator) 
        {
            $decorator->afterDecorate();
        }
    }

}

//装饰器——T恤
class Tshirt implements ClothesDecorator
{
    public function beforeDecorate()
    {
        echo "出门前穿上T恤\n";
    }

    public function afterDecorate()
    {
        echo "回家后脱掉T恤\n";
    }
}

//装饰器——短裤
class Shorts implements ClothesDecorator
{
    public function beforeDecorate()
    {
        echo "出门前穿上短裤\n";
    }

    public function afterDecorate()
    {
        echo "回家后脱掉短裤\n";
    }
}

//装饰器——拖鞋
class Sandals implements ClothesDecorator
{
    public function beforeDecorate()
    {
        echo "出门前穿上拖鞋\n";
    }

    public function afterDecorate()
    {
        echo "回家后脱掉拖鞋\n";
    }
}

$person = new Person("张三");
$person->show(); //啥也不穿，直接出门

$person->addDecorate(new Tshirt()); //添加装饰器
$person->addDecorate(new Shorts());
$person->addDecorate(new Sandals());
$person->show(); //展示


/*
装饰器可以批量添加，也可以批量卸载，灵活方便
*/
